package rabbitmq

import (
	"github.com/streadway/amqp"
	"log"
)

// MQ相关配置信息
type RabbitMQ struct {
	Conn         *amqp.Connection // 连接
	Ch           *amqp.Channel    // 通道
	QueueName    string           // 队列名称
	ExchangeName string           // 交换机名称
	ExchangeType string           // 交换机类型
	ExchangeKey  string           // routingKey
}

type QueueAndExchange struct {
	QueueName    string           // 队列名称
	ExchangeName string           // 交换机名称
	ExchangeType string           // 交换机类型
	ExchangeKey  string           // routingKey
}


// 打印错误信息
func FailOnError(err error, msg string) {
	if err != nil {
		log.Fatalf("%s: %s", msg, err)
	}
}

// 连接MQ
func (r *RabbitMQ) ConnMQ() {
	conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
	FailOnError(err, "Failed to connect to RabbitMQ")
	r.Conn = conn
}

// 关闭MQ
func (r *RabbitMQ) CloseMQ() {
	err := r.Conn.Close()
	FailOnError(err, "Failed to close to RabbitMQ")
}

// 创建通道
func (r *RabbitMQ) CreateChannel() {
	channel, err := r.Conn.Channel()
	FailOnError(err, "Failed to create to Channel")
	r.Ch = channel
}

// 关闭通道
func (r *RabbitMQ) CloseChannel() {
	err := r.Ch.Close()
	FailOnError(err, "Failed to close to Channel")
}

// 生产者 
func (r *RabbitMQ) PublishMsg(body string) {

	ch := r.Ch

	// 创建队列
	_, err1 := ch.QueueDeclare(r.QueueName, true, false, false, false, nil)
	FailOnError(err1, "")

	// 创建交换机
	err2 := ch.ExchangeDeclare(r.ExchangeName, r.ExchangeType, true, false, false, false, nil)
	FailOnError(err2, "")

	// 队列绑定交换机
	err3 := ch.QueueBind(r.QueueName, r.ExchangeKey, r.ExchangeName, false, nil)
	FailOnError(err3, "")

	// 发送消息
	err4 := ch.Publish(r.ExchangeName, r.ExchangeKey, false, false, amqp.Publishing{
		ContentType:     "text/plain",
		DeliveryMode:    amqp.Persistent,
		Body:            []byte(body),
	})
	FailOnError(err4, "")

}

func NewRabbitMQ(qe QueueAndExchange) *RabbitMQ {
	return &RabbitMQ{
		QueueName:    qe.QueueName,
		ExchangeName: qe.ExchangeName,
		ExchangeType: qe.ExchangeType,
		ExchangeKey:  qe.ExchangeKey,
	}
}
